#include <iostream>
#include "./static_lib_output/sum.h"
#include "./static_lib_output/sub.h"

using namespace std;

//ldd 程序名称
//可以查看这个程序依赖哪些动态库

//在linux中,如果是静态库,库文件是以.so作为后缀的
//如果是动态库,库文件是以.a作为后缀的
//库文件的命名一般是:libxxx.so 或者 libxxx.a
//那么库的真实名称是去掉lib前缀,还要去掉.a .so 后缀,剩下的就是库名称

//程序在编译的时候,会经历四步
//预处理->编译->汇编->链接分别形成三个临时文件
//.i    ->.s  ->.o
//其中.o是可重定向二进制文件
//对于c++,我们把除了有main函数.cc文件的其他一些.cc文件
//在汇编所形成的.o文件所打包,这个包就叫做库

//静态库:程序在编译链接的时候,把库的代码连接到可执行文件中
//程序运行的时候将不需要静态库
//动态库:程序在运行的时候才去链接动态库的代码
//多个程序共享使用库的代码

//静态库的缺点:
//1.加载到内存时所占空间大
//2.多个进程使用用一个库,会导致内存资源的浪费
//优点:
//1.与库无关,库已经链接到可执行程序中了,删除库后,依然可以运行

//动态库的缺点:
//1.依赖库,如果可执行程序生成后,删除库则无法运行这个可执行程序
//优点:
//1.节省内存空间资源

//一套完整的库包含三个部分:
//1.库文件本身
//2.相关的头文件
//3.库文件的说明文档

//我们在c/c++中,为什么有时候,在.h文件里面实现声明
//.c/.cpp里面实现定义?
//除了这样分离处理,可以更加后续的维护之外
//那么跟库的制作也有关系
//变得更加方便使用和私密了

//下面讲讲如何生成静态库
//就以我们实现的这个静态库为例子
//首先是sum.h sub.h sum.cc sub.cc 
//里面写好声明和定义将sum.cc和sub.cc编译成.o文件
//然后就可以打包这两个.o文件进行打包,形成静态库
//ar -rc libmymath.a sum.o sub.o
//其中ar是gnu归档工具,其中r表示replace c表示create
//表示生成静态库的.o文件发生改变时会更新静态库
//如果需要查看静态库里面的文件,使用如下的命令
//ar -tv libmymath.a
//其中t表示列出静态库中的文件,v表示显示详细信息

//有了静态库之后,那么就是如何使用它了
//生成静态可执行程序采用如下的命令
//g++ test.cc -I./static_lib_output -L./static_lib_output -lmymath -o test -std=c++11
//其中-I+头文件搜索路径,-L+库文件搜索路径,-l+指明链接哪一个库

//我们之前写的代码,也用了库的啊,为啥就没有指明这些选项呢?
//之前的库,在系统的默认路径下:头文件是/usr/include ,库文件是/lib64 
//编译器是能够识别这些路径的
//也就是说如果我不想带这些选项
//那么我可以把头文件和库拷贝到默认的路径下面
//注意：
//1.此时在生成可执行程序时不需要指明库路径和头文件路径，但还是要指明库名称。
//2.我们在编译c语言的库不需要指明库名称因为编译器自己会自动找到库名称


int main()
{
    int x = 30;
    int y = 20;
    
    int ret_sum = sum(x, y);
    int ret_sub = sub(x, y);
    cout << ret_sum << endl;
    cout << ret_sub << endl;
    return 0;
}
